home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / The Hacks! / mhTV ƒ / TVSource / SourceThatMatters / Import / TVImportComponent.c < prev    next >
C/C++ Source or Header  |  1998-06-20  |  14KB  |  467 lines

  1. #include "Maynard.h"
  2. #include "ComponentHelp.h"
  3.  
  4. #include <Files.h>
  5. #include <FixMath.h>
  6. #include <Resources.h>
  7. #include <ToolUtils.h>
  8. #include <QuickTimeComponents.h>
  9. #include <MediaHandlers.h>
  10.  
  11. #include "TVImportVersion.h"
  12.  
  13. ///=============================================================================
  14.  
  15. #if STAND_ALONE
  16.     #define ImportTVDispatchSelector main
  17. #else
  18.     Component RegisterTVImport(void);
  19. #endif //STAND_ALONE
  20. pascal ComponentResult ImportTVDispatchSelector(
  21.   ComponentParameters *paramsPtr, Handle thiss);
  22.  
  23. ///=============================================================================
  24.  
  25. #define kMovieTimeScale              600
  26. #define kMPEGTrackTimeScale        600
  27.  
  28. struct TVImportRecord{
  29.     MovieImportComponent self;
  30. };
  31. typedef struct TVImportRecord TVImportRecord;
  32.  
  33. ///-----------------------------------------------------------------------------
  34.  
  35. #define STATIC static
  36. #define COMPONENT 
  37.  
  38. STATIC COMPONENT ComponentResult TVImportOpen(
  39.   TVImportRecord* thiss, MovieImportComponent self);
  40. STATIC COMPONENT ComponentResult TVImportClose(
  41.   TVImportRecord* thiss, MovieImportComponent self);
  42. STATIC COMPONENT ComponentResult TVImportCanDo(
  43.   TVImportRecord* thiss, short selector);
  44. STATIC COMPONENT ComponentResult TVImportVersion(
  45.   TVImportRecord* thiss);
  46.  
  47. STATIC COMPONENT TVImportGetMIMETypeList(
  48.   TVImportRecord* thiss, QTAtomContainer* containerPtr);
  49. STATIC COMPONENT ComponentResult ImportTVImportFile(
  50.   TVImportRecord* thiss, FSSpec const* fsSpecPtr, 
  51.   Movie movie, Track targetTrack, Track* usedTrackPtr, 
  52.   TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr);
  53. STATIC COMPONENT ComponentResult ImportTVImportDataRef( 
  54.   TVImportRecord* thiss, Handle dataRef, OSType dataRefType,
  55.   Movie movie, Track targetTrack, Track* usedTrackPtr, 
  56.   TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr);
  57. STATIC COMPONENT ComponentResult TVImportValidate(
  58.   TVImportRecord* thiss, FSSpec const* fsSpecPtr, Handle dataH, 
  59.   Boolean* fValidPtr);
  60.  
  61. ///-----------------------------------------------------------------------------
  62.  
  63. static ComponentResult SG_DoTheImport( 
  64.   TVImportRecord* thiss, 
  65.   Movie theMovie, Track targetTrack, Track* usedTrackPtr, 
  66.   TimeValue atTime, TimeValue* addedTimePtr, 
  67.   long inFlags, long* outFlagsPtr);
  68.  
  69. ///*****************************************************************************
  70.  
  71. #if GENERATINGPOWERPC
  72. //Note that while this struct may appear to be a static variable, it 
  73. // actually MUST be exported because it is the entry point used by the 
  74. // component manager when it connects to this code fragment.
  75. struct RoutineDescriptor ImportTVSelectorDispatcher
  76.   =BUILD_ROUTINE_DESCRIPTOR(
  77.      kPascalStackBased
  78.     |RESULT_SIZE(kFourByteCode)
  79.     |STACK_ROUTINE_PARAMETER(1,kFourByteCode)
  80.     |STACK_ROUTINE_PARAMETER(2,kFourByteCode),
  81.     ImportTVDispatchSelector);
  82. #endif //GENERATINGPOWERPC
  83.  
  84. ///-----------------------------------------------------------------------------
  85.  
  86. #if !STAND_ALONE
  87. Component RegisterTVImport(void)
  88. {
  89. #if GENERATINGPOWERPC
  90.     #define componentEntryPoint &ImportTVSelectorDispatcher
  91.     #define registrationFlags   0x200|registerComponentGlobal
  92.     //Note the 0x200 tells RegisterComponent() we are PPC native.
  93. #else
  94.     #define componentEntryPoint TVImportDispatchSelector
  95.     #define registrationFlags   registerComponentGlobal
  96. #endif
  97. #define kFileType        \
  98.     canMovieImportFiles|canMovieImportInPlace
  99.  
  100.     ComponentDescription cd;
  101.     Component            registeredComponent;
  102.  
  103.     //Remove any older versions of this component.
  104.     cd.componentType        =MovieImportType;
  105.     cd.componentManufacturer=0;
  106.     cd.componentFlags       =0;
  107.     cd.componentFlagsMask   =0;
  108.  
  109. /*
  110. opens file type mhTV
  111. is initially an empty file 
  112.    -- so this sets (makes up)
  113.       height/width
  114.       duration (max)
  115.       movie controller
  116.       (what else)
  117.    -- so can kill all the MPEG and mpyc/WIRED components
  118.    
  119. then add so pops up a dialog for the VDIG and stores results
  120.  
  121. plus try strange matrix/effects  
  122. */
  123.  
  124.     cd.componentSubType     =FOUR_CHAR_CODE('mhTV');
  125.     registeredComponent=NULL;
  126.     do{
  127.         registeredComponent=FindNextComponent(registeredComponent, &cd);
  128.         UnregisterComponent(registeredComponent);
  129.     }while(registeredComponent);
  130.  
  131. ///.............................................................................
  132.  
  133.     //Now register this component to eat muxed MPEG.
  134.     cd.componentType        =MovieImportType;
  135.     cd.componentManufacturer=FOUR_CHAR_CODE('mhTV');
  136.     cd.componentFlagsMask   =0;
  137.  
  138.     cd.componentSubType     =FOUR_CHAR_CODE('mhTV');
  139.     cd.componentFlags       =kFileType|canMovieImportValidateFile;
  140.     cd.componentFlagsMask   =0;
  141.     registeredComponent=RegisterComponent(&cd, 
  142.       componentEntryPoint, registrationFlags, 0, 0, 0);
  143.     SetDefaultComponent(registeredComponent, 
  144.       defaultComponentAnyFlagsAnyManufacturer);
  145.  
  146.     return registeredComponent;
  147. }
  148. #endif //STAND_ALONE
  149. ///-----------------------------------------------------------------------------
  150.  
  151. pascal ComponentResult ImportTVDispatchSelector(
  152.   ComponentParameters* paramsPtr, Handle thiss)
  153. {
  154. #define cmpGlobalParm REINTERPRET_CAST(TVImportRecord*, thiss)
  155.  
  156.     ComponentResult error=badComponentSelector;
  157.  
  158.     switch(paramsPtr->what){
  159.  
  160.     ///.........................................................................
  161.     //Component manager selectors.
  162.     case kComponentOpenSelect:
  163.         error=TVImportOpen( 
  164.           CMP1(MovieImportComponent) );
  165.         break;
  166.     case kComponentCloseSelect:
  167.         error=TVImportClose( 
  168.           CMP1(MovieImportComponent) );
  169.         break;
  170.     case kComponentCanDoSelect: 
  171.         error=TVImportCanDo( 
  172.           CMP1(short) );
  173.         break;
  174.     case kComponentVersionSelect:
  175.         error=TVImportVersion( 
  176.           CMP0() );
  177.         break;
  178.  
  179.     ///.........................................................................
  180.     //Import component selectors.
  181.     case kMovieImportValidateSelect: 
  182.         error=TVImportValidate( 
  183.           CMP3(FSSpec const*, Handle, Boolean*) );
  184.         break;
  185.     case kMovieImportFileSelect: 
  186.         error=ImportTVImportFile( 
  187.           CMP8(FSSpec const*, Movie, Track, Track*, 
  188.             TimeValue, TimeValue*, long, long*) );
  189.         break;
  190.     case kMovieImportDataRefSelect:
  191.         error=ImportTVImportDataRef( 
  192.           CMP9(Handle, OSType, Movie, Track, Track*, 
  193.             TimeValue, TimeValue*, long, long*) );        
  194.         break;
  195.     }
  196.  
  197.     return error;
  198. }
  199. ///=============================================================================
  200.  
  201. STATIC COMPONENT ComponentResult TVImportVersion(TVImportRecord* thiss)
  202. {
  203. #pragma unused (thiss)
  204.     return kTVImportVersion;
  205. }
  206. ///-----------------------------------------------------------------------------
  207.  
  208. STATIC COMPONENT ComponentResult TVImportCanDo(TVImportRecord* thiss, 
  209.   short functionNumber)
  210. {
  211. #pragma unused (thiss)
  212.  
  213.     switch(functionNumber){
  214.     case kComponentOpenSelect: 
  215.     case kComponentCloseSelect: 
  216.     case kComponentCanDoSelect: 
  217.     case kComponentVersionSelect: 
  218.  
  219.     case kMovieImportGetMIMETypeListSelect:
  220.     case kMovieImportValidateSelect:
  221.     case kMovieImportFileSelect:
  222.     case kMovieImportDataRefSelect:
  223.         return TRUE;
  224.  
  225.     default:
  226.         return FALSE;
  227.     }
  228. }
  229. ///=============================================================================
  230.  
  231. STATIC COMPONENT ComponentResult TVImportOpen(TVImportRecord* dummy, 
  232.   MovieImportComponent self)
  233. {
  234. #pragma unused(dummy)
  235.  
  236.     //This component does not use any class meta-data hence we are spared the
  237.     // hassle of handling global memory allocation from the system heap.
  238.  
  239.     OSErr error=noErr;
  240.     TVImportRecord* thiss;
  241.  
  242.     ASSERT(self!=NULL);
  243.  
  244.     thiss=STATIC_CAST(TVImportRecord*, 
  245.       NewPtrClear( sizeof(TVImportRecord)) );
  246.     if(thiss==NULL){
  247.         error=MemError();
  248.         FLAG_ERROR(error);
  249.         goto cleanup;
  250.     }
  251.     SetComponentInstanceStorage(self, STATIC_CAST(Handle, thiss) );
  252.  
  253.     thiss->self=self;
  254.     
  255.     goto done;
  256.     
  257. cleanup:
  258.     //No cleanup to do.
  259. done:
  260.     return error;
  261. }
  262. ///-----------------------------------------------------------------------------
  263.  
  264. STATIC COMPONENT ComponentResult TVImportClose(TVImportRecord* thiss, 
  265.   MovieImportComponent self)
  266. {
  267. #pragma unused(self)
  268.  
  269.     DisposePtr( STATIC_CAST(Ptr, thiss) );
  270.     return noErr;
  271. }
  272. ///=============================================================================
  273.  
  274. STATIC COMPONENT ComponentResult ImportTVImportFile(TVImportRecord* thiss, 
  275.   FSSpec const* fsSpecPtr, 
  276.   Movie movie, Track targetTrack, Track* usedTrackPtr, 
  277.   TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr)
  278. {
  279.     OSErr error;
  280.     AliasHandle fileAliasH=NULL;
  281.  
  282.     ASSERT(fsSpecPtr!=NULL);
  283.  
  284.     error=NewAliasMinimal(fsSpecPtr, &fileAliasH);
  285.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  286.     error=ImportTVImportDataRef(thiss, 
  287.       STATIC_CAST(Handle, fileAliasH), rAliasType, 
  288.       movie, targetTrack, usedTrackPtr, 
  289.       atTime, addedTimePtr, inFlags, outFlagsPtr);
  290.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  291.     goto done;
  292.  
  293. cleanup:
  294.     //No cleanup necessary.
  295. done:
  296.     DisposeHandle( STATIC_CAST(Handle, fileAliasH) );
  297.     return error;
  298. }
  299. ///-----------------------------------------------------------------------------
  300.  
  301. STATIC COMPONENT ComponentResult ImportTVImportDataRef(TVImportRecord* thiss, 
  302.   Handle dataRef, OSType dataRefType,
  303.   Movie movie, Track targetTrack, Track* usedTrackPtr, 
  304.   TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr)
  305. {
  306.     ComponentResult error;
  307.     Component   dataHandlerClass;
  308.     DataHandler dataHandler=NULL;
  309.  
  310.     ASSERT(thiss!=NULL);
  311.     ASSERT(dataRef!=NULL);
  312.     ASSERT(movie!=NULL);
  313.  
  314.     //A targetTrack of non-NULL is for importing into a specific track rather 
  315.     // than a movie. 
  316.     //It's not clear that we'll ever have to support this for mhTV.
  317.     if(targetTrack!=NULL){
  318.         error=paramErr;    FLAG_ERROR(error); goto cleanup;
  319.     }
  320.  
  321.     dataHandlerClass=GetDataHandler(dataRef, dataRefType, kDataHCanRead);
  322.     if(dataHandlerClass==NULL){
  323.         error=cantOpenHandler; FLAG_ERROR(error); goto cleanup;    
  324.     }
  325.     error=OpenAComponent(dataHandlerClass, &dataHandler);
  326.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  327.     error=DataHSetDataRef(dataHandler, dataRef );
  328.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  329.  
  330.     //Make the movie point to the selected file
  331.     SetMovieDefaultDataRef(movie, dataRef, dataRefType);
  332.  
  333.     error=SG_DoTheImport(thiss, movie, targetTrack, usedTrackPtr, 
  334.         atTime, addedTimePtr, inFlags, outFlagsPtr);
  335.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  336.     goto done;
  337.  
  338. cleanup:
  339.     //No cleanup necessary.
  340. done:
  341.     CloseComponent(dataHandler);
  342.     return error;
  343. }
  344. ///-----------------------------------------------------------------------------
  345.  
  346. static ComponentResult SG_DoTheImport(TVImportRecord* thiss, 
  347.   Movie movie, Track targetTrack, Track* usedTrackPtr, 
  348.   TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr)
  349. {
  350. #pragma unused (thiss, addedTimePtr, inFlags)
  351.  
  352.     //This is full volume (1.0 in 8.8 format).
  353.     const int kSuggestedMovieVolume=0x100;
  354.  
  355.     ComponentResult error;
  356. //    ComponentResult mediaHandlerStatus;
  357.  
  358.     long                sampleOffset, sampleSize;
  359.     OSType              mhlrType;
  360.     Track                 mpegTrack=NULL;
  361.     Media               mpegMedia=NULL;
  362.     long                suggestedMovieWidth;
  363.     long                  suggestedMovieHeight;
  364.     TimeValue           mpegTrackDuration=0;
  365.     Fixed               fxEditRate;
  366.     long                outFlags;
  367.  
  368.     QTAtomContainer     sampleInfoContainer=NULL;
  369.     Size                sampleInfoContainerSize;
  370.     Handle              h=NULL;
  371.     SampleDescription*  sampleDescriptionAlias;
  372.  
  373.     ASSERT(thiss!=NULL);
  374.     ASSERT(movie!=NULL);
  375.     ASSERT(targetTrack==NULL);
  376.  
  377.     error=QTNewAtomContainer(&sampleInfoContainer);
  378.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  379.  
  380.  
  381.        sampleInfoContainerSize=GetHandleSize(sampleInfoContainer);
  382.     h=NewHandleClear(
  383.       sizeof(SampleDescription) ); //(+sampleInfoContainerSize );
  384.     if(h==NULL) {error=MemError(); FLAG_ERROR(error); goto cleanup;}
  385.  
  386.     sampleDescriptionAlias=STATIC_CAST(SampleDescription*, *h);
  387.     sampleDescriptionAlias->descSize
  388.       =sizeof(SampleDescription);// +sampleInfoContainerSize;
  389.     sampleDescriptionAlias->dataFormat=0;
  390. //      =sgEMPEGToSampleDescriptionDataFormat[mpegType];
  391.     sampleDescriptionAlias->resvd1      =0;
  392.     sampleDescriptionAlias->resvd2      =0;
  393.     sampleDescriptionAlias->dataRefIndex=0;
  394.     //BlockMoveData(*sampleInfoContainer, (*h)+sizeof(SampleDescription), 
  395.     //  sampleInfoContainerSize );
  396.  
  397. ///.............................................................................
  398.  
  399.     SetMovieTimeScale(movie, kMovieTimeScale);
  400.  
  401.     suggestedMovieWidth =320;
  402.     suggestedMovieHeight=240;
  403.     mpegTrack=NewMovieTrack(movie, 
  404.       suggestedMovieWidth<<16, suggestedMovieHeight<<16, kSuggestedMovieVolume);
  405.     error=GetMoviesError();
  406.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  407.     mhlrType='mhTV';
  408.     mpegMedia=NewTrackMedia(mpegTrack, mhlrType, 
  409.       kMPEGTrackTimeScale, NULL, 0);      
  410.     error=GetMoviesError();
  411.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  412.  
  413.     mpegTrackDuration=0x7FFFFFFF;
  414.     sampleOffset=0;
  415.     sampleSize  =1;
  416.     error=AddMediaSampleReference(mpegMedia, 
  417.       sampleOffset, sampleSize, mpegTrackDuration, 
  418.       STATIC_CAST(SampleDescriptionHandle, h), 1, 0, NULL);
  419.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  420.  
  421.     fxEditRate=kfxOne;
  422.     error=InsertMediaIntoTrack(mpegTrack, atTime, 0, 
  423.       mpegTrackDuration, fxEditRate);
  424.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  425.  
  426.     SetTrackEnabled(mpegTrack, TRUE);
  427.     error=GetMoviesError();
  428.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  429. {
  430. RGBColor rgb;
  431. rgb.red  =0x0FFF;
  432. rgb.green=0x0000;
  433. rgb.blue =0x0000;
  434.     error=MediaSetGraphicsMode( GetMediaHandler(mpegMedia), 
  435.       ditherCopy, NULL );
  436. //(      addMax, &rgb );
  437.     if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
  438. }
  439.     goto done;
  440.     
  441. cleanup:
  442.     DisposeMovieTrack(mpegTrack);
  443.     mpegTrack=NULL;
  444.  
  445. done:
  446.     QTDisposeAtomContainer(sampleInfoContainer);
  447.     DisposeHandle(h);
  448.     if(usedTrackPtr) *usedTrackPtr=mpegTrack;
  449.     if(addedTimePtr) *addedTimePtr=mpegTrackDuration;
  450.     outFlags=0;
  451.     if(outFlagsPtr) *outFlagsPtr=outFlags;
  452.  
  453.     return error;
  454. }
  455. ///=============================================================================
  456.  
  457. STATIC COMPONENT ComponentResult TVImportValidate(TVImportRecord* thiss, 
  458.   FSSpec const* fsSpecPtr, Handle dataH, Boolean* fValidPtr)
  459. {
  460. #pragma unused (thiss, fsSpecPtr, dataH)
  461.     ASSERT(fValidPtr!=NULL);
  462.  
  463.     *fValidPtr=TRUE;
  464.     return noErr;
  465. }
  466. ///=============================================================================
  467.